package com.infolab.aims.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JExcelApiExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.infolab.aims.GlobalConstant;
import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.CommonUtil;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.exception.StockFreezeException;
import com.infolab.aims.domain.SystemUser;
import com.infolab.aims.domain.asset.AssetBalance;
import com.infolab.aims.domain.asset.AssetComponent;
import com.infolab.aims.domain.asset.AssetEquipmentView;
import com.infolab.aims.domain.asset.AssetModel;
import com.infolab.aims.service.intf.AssetModelService;
import com.infolab.aims.service.intf.AssetTransactionService;
import com.infolab.aims.service.intf.LocationService;


@Controller
@RequestMapping("/monthEndClosing")
@SessionAttributes(value=MonthEndClosingController.SESSION_SEARCH_CRITERIA)
public class MonthEndClosingController extends AbstractController {

	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/monthEndClosing";
	public static final String JSP_MAIN_FORM_FREEZE="monthEndClosingFormFreeze";
	public static final String JSP_MAIN_FORM_ACCOUNT="monthEndClosingFormAccount";
	public static final String JSP_MAIN_SEARCH="monthEndClosingSearch";

	@Autowired
	AssetModelService assetModelService;

	@Autowired
	AssetTransactionService assetTransactionService;
	
	@Autowired
	LocationService locationService;

	Log logger = LogFactory.getLog(getClass());
	
	@RequestMapping(value="create", method = RequestMethod.GET)
	public String createMonthEndClosing(Model model, HttpServletRequest request) {
		AssetModel assetModel = new AssetModel();
		assetModel.setActive(true);
		String departmentId = request.getParameter("departmentId");
		model.addAttribute(assetModel);
		model.addAttribute("departmentId", departmentId);
		model.addAttribute("currentMonth", DateFormatUtils.format(new Date(), "yyyy-MM"));
		model.addAttribute("departments", request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_DEPARTMENT));
		String status = request.getParameter("status");
		if(StringUtils.equals(status, "freeze")){
			Map<String, String> locks = (Map<String, String>) request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCK);
			SystemUser systemUser = (SystemUser) request.getSession().getAttribute(GlobalConstant.SESSION_CURRENT_SYSTEMUSER);
			if(systemUser.isSuperAdmin()){	
				String lock = StringUtils.defaultIfEmpty(locks.get(departmentId), "0");
				model.addAttribute("lockFlag", lock);
			}else{
				if(systemUser.getDepartment() != null && StringUtils.equals(departmentId, String.valueOf(systemUser.getDepartment().getDepartmentId()))){
					String lock = StringUtils.defaultIfEmpty(locks.get(String.valueOf(systemUser.getDepartment().getDepartmentId())), "0");
					model.addAttribute("lockFlag", lock);
				}
			}
			return JSP_MAIN_FORM_FREEZE;
		}else{
			return JSP_MAIN_FORM_ACCOUNT;
		}
	}

	@RequestMapping(value="create",method=RequestMethod.POST)
	public String saveMonthEndClosing(Model model, HttpServletRequest request, @ModelAttribute("assetModel") AssetModel assetModel, BindingResult result) {

		String date = request.getParameter("currentMonth");
		String freeze = request.getParameter("freeze");
		String status = request.getParameter("status");
		String departmentId = request.getParameter("departmentId");
		if(StringUtils.equals(status, "freeze")){
			String val = StringUtils.defaultIfEmpty(freeze, "0");
			Map<String, String> lockMap = (Map<String, String>)request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCK);
			lockMap.put(departmentId, val);
			if(StringUtils.equals(val, "1"))
				setSuccessMessage(getMessageResources("success.freeze"));
			else
				setSuccessMessage(getMessageResources("success.unfreeze"));
			return "redirect:"+CONTEXT_PATH+"/create?status=freeze&departmentId="+departmentId;	
		}else{
			String year = StringUtils.split(date, "-")[0];
			String month = StringUtils.split(date, "-")[1];
			List<String> message = assetModelService.createAssetBalance(month, year, getCurrentUserName(request));
			if(CollectionUtils.isNotEmpty(message)){
				model.addAttribute("currentMonth", date);
				model.addAttribute("departments", request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_DEPARTMENT));
				for(String msg : message){
					result.reject("error.monthEndClosing.inPending", new String[]{msg}, "");
				}
				return JSP_MAIN_FORM_ACCOUNT;
			}else{
				setSuccessMessage(getMessageResources("success.create","Month End Closing"));
				return "redirect:"+CONTEXT_PATH+"/search";	
			}
		}

	}
	
	@RequestMapping(value="search",method=RequestMethod.GET)
	public String searchMonthEndClosing(@ModelAttribute(SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria,@ModelAttribute("currentSearchCriteria") SearchCriteria currentSearchCriteria,Model model) {

		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());

		List<AssetBalance> searchResult = assetModelService.searchAssetBalance(currentSearchCriteria);
		model.addAttribute("searchResult", searchResult);

		return JSP_MAIN_SEARCH;
	}


	@ModelAttribute(AssetModelController.SESSION_SEARCH_CRITERIA)
	public SearchCriteria getAssetModelSearchCriteria()
	{
		return new SearchCriteria();
	}

	//not use now at 2011-7-7
	@RequestMapping(value={"printAssetEquipment"}, method = RequestMethod.GET)
	public void printAssetEquipment(Model model,@RequestParam(value="locationId",required=true)Integer locationid, HttpServletResponse response) throws IOException {

		try
		{
			ServletOutputStream servletOutputStream = response.getOutputStream();	
			InputStream reportStream = null;
		
			SearchCriteria searchCriteria = new SearchCriteria();
			searchCriteria.addSearchCriteria("locationId", locationid);
			List<AssetEquipmentView> list = assetModelService.findAssetEquipmentsView(searchCriteria);
			
			reportStream =getClass().getClassLoader().getResourceAsStream("report/AssetEquipments.jasper");	
//			JasperRunManager.runReportToPdfStream(reportStream,
//					servletOutputStream,
//					null,
//					new JRBeanCollectionDataSource(list));
			
			JasperPrint jasperPrint = JasperFillManager.fillReport(reportStream, null, new JRBeanCollectionDataSource(list));

			JExcelApiExporter exporterXLS = new JExcelApiExporter();
			exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, servletOutputStream );
			response.setHeader("Content-Disposition", "attachment; filename=ASSET_EQUIPMENT.xls");
			response.setContentType("application/vnd.ms-excel");
			exporterXLS.exportReport();
			servletOutputStream.flush();
			servletOutputStream.close();
		}
		catch (JRException e)
		{
			logger.error(CommonUtil.getStackTrace(e));
			// display stack trace in the browser
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/plain");
			response.getOutputStream().print(stringWriter.toString());
		}

	}
	
	//not use now at 2011-7-7
	@RequestMapping(value={"printAssetComponent"}, method = RequestMethod.GET)
	public void printAssetComponent(Model model,HttpServletRequest request,HttpServletResponse response) throws IOException {

		try
		{
			ServletOutputStream servletOutputStream = response.getOutputStream();	
			InputStream reportStream = null;
		
			SearchCriteria searchCriteria = new SearchCriteria();
			List<AssetComponent> list = assetModelService.findAssetComponents(searchCriteria);

			reportStream =getClass().getClassLoader().getResourceAsStream("report/AssetComponents.jasper");	
//			JasperRunManager.runReportToPdfStream(reportStream,
//					servletOutputStream,
//					null,
//					new JRBeanCollectionDataSource(assetComponents));
//					
//			response.setContentType("application/pdf");
//			servletOutputStream.flush();
//			servletOutputStream.close();
			JasperPrint jasperPrint = JasperFillManager.fillReport(reportStream, null, new JRBeanCollectionDataSource(list));

			JExcelApiExporter exporterXLS = new JExcelApiExporter();
			exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, servletOutputStream );
			response.setHeader("Content-Disposition", "attachment; filename=ASSET_COMPONENTS.xls");
			response.setContentType("application/vnd.ms-excel");
			exporterXLS.exportReport();
			servletOutputStream.flush();
			servletOutputStream.close();
		}
		catch (JRException e)
		{
			logger.error(CommonUtil.getStackTrace(e));
			// display stack trace in the browser
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/plain");
			response.getOutputStream().print(stringWriter.toString());
		}

	}
	
	//not use now at 2011-7-7
	@RequestMapping(value={"printAssetBalance"}, method = RequestMethod.GET)
	public void printAssetBalance(Model model,@ModelAttribute(SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria, HttpServletRequest request,HttpServletResponse response) throws IOException {

		try
		{
			String month = request.getParameter("month");
			String year = request.getParameter("year");
			String type = request.getParameter("type");
			searchCriteria.addSearchCriteria("month", month);
			searchCriteria.addSearchCriteria("year", year);
			searchCriteria.addSearchCriteria("type", type);
			
			List<AssetBalance> list = assetModelService.findAssetBalance(searchCriteria);
	
			ServletOutputStream servletOutputStream = response.getOutputStream();	
			InputStream reportStream = null;
			
			reportStream =getClass().getClassLoader().getResourceAsStream("report/AssetBalances.jasper");	
			JasperPrint jasperPrint = JasperFillManager.fillReport(reportStream, null, new JRBeanCollectionDataSource(list));
			JExcelApiExporter exporterXLS = new JExcelApiExporter();
			exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
			exporterXLS.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
			exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, servletOutputStream );
			response.setHeader("Content-Disposition", "attachment; filename=ASSET_BLANCES.xls");
			response.setContentType("application/vnd.ms-excel");
			exporterXLS.exportReport();
			servletOutputStream.flush();
			servletOutputStream.close();
		}
		catch (JRException e)
		{
			logger.error(CommonUtil.getStackTrace(e));
			// display stack trace in the browser
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/plain");
			response.getOutputStream().print(stringWriter.toString());
		}

	}
	
}
